<%@ page pageEncoding="UTF-8"%>
<%@ page import="java.util.Map.Entry,java.util.*,java.util.regex.*,java.net.*,java.io.*,java.text.*"%>
<%@ page import="com.tianxiabuyi.*,com.tianxiabuyi.persist.*,com.tianxiabuyi.model.pojo.*,com.tianxiabuyi.utils.*"%>
<%@ page import="com.alibaba.fastjson.TypeReference" %>
<%!
	// 查询用户名是否存在
	List userNames(String userName, Integer hospital) {
		return QBuilder.db("basedb").select().from("User").where(new Where("userName=", userName).and("status=", STATUS_ENABLE).and("hospital=", hospital)).page(1,1).query().getResultObj();
	}

	public Long age2birth(int age) {
		Calendar cal = Calendar.getInstance();
		cal.add(Calendar.YEAR, -age);
		return cal.getTime().getTime();
	}

	public int birth2age(long birth) {
		Calendar cal = Calendar.getInstance();
		int year = cal.get(Calendar.YEAR);
		cal.setTime(new Date(birth));
		int y = cal.get(Calendar.YEAR);
		return year - y;
	}

	// 登录 用户名或手机号，密码登录
	Message login(User user) {
		return login(user, null, null, null, null);
	}

	// 第三方登录
	Message login(String source, String unionId, Integer type, Integer hospital) {
		return login(null, source, unionId, type, hospital);
	}

	// 登录
	Message login(User user, String source, String unionId, Integer type, Integer hospital) {
		Message msg = new Message();
		User u = null;
		if (null == user) {
			List<Integer> uids = QBuilder.db("basedb").select("u.id").from("UserAccount as ua, User as u").where(new Where("ua.uid=u.id").and("ua.source=", source).and("ua.unionId=", unionId).and("ua.status=", STATUS_ENABLE).and("u.status=", STATUS_ENABLE).and("u.type=", type).and("u.hospital=", hospital).and("ua.hospital=", hospital)).query().getResultObj();
			if (isEmpty(uids)) {
				msg = new Message(30021, "第三方登录失败");
				return msg;
			}
			u = userByUid(uids.get(0));
			if (isEmpty(u)){
				msg = new Message(30021, "第三方登录失败");
				return msg;
			}
		} else {
			String userName = user.getUserName();
			String password = user.getPassword();
			Integer hospitalId = user.getHospital();
			List<User> users = QBuilder.db("basedb").select().from("User as u").where(new Where("u.password=", password).and("u.type=", user.getType()).and("u.status=", STATUS_ENABLE).and("u.hospital=", hospitalId).and("(u.userName = '" + userName + "' or u.phone='" + userName + "')")).page(1, 1).query().getResultObj();
			if (isEmpty(users)) { // 登录失败
				msg = new Message(30022, "手机号或密码不正确");
				return msg;
			}
			// 设置最后登录时间和ip
			u = users.get(0);
		}
		hospital = u.getHospital();
		u.setLastLogin(System.currentTimeMillis());
		Map userJson = u.getJson();
		if (user != null) {
			userJson.put("ip", Tools.getDesc(user.getJson("ip"), ""));
			userJson.put("from", Tools.getDesc(user.getJson("from"), ""));
			userJson.put("token", Tools.getDesc(user.getJson("token"), ""));
		}
		u.setJson(userJson);
		u.setUserName(u.getUserName());
		DBTools.db("basedb").modItem(u, u.getId());

		// 根据用户类型展示不同的信息
		Map<String, Object> jsonMap = new HashMap<String, Object>();
		jsonMap.put("uid", u.getId());
		jsonMap.put("user_name", u.getUserName());
		jsonMap.put("name", u.getName());
		Integer userType = u.getType();
		jsonMap.put("type", userType + "");
		if (USER_PATIENT.equals(userType) || SIGN_PATIENT.equals(userType)) { // 普通用户
			setUserInfo(u, jsonMap);
		} else if(USER_EMPLOYEE.equals(userType) || SIGN_EMPLOYEE.equals(userType)) { // 医院员工
			setEmployeeInfo(u, jsonMap);
		}
		Map tokenMap = token(u);
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("token", tokenMap.get("token"));
		map.put("expires_in", tokenMap.get("expireIn"));
		Map<String, Object> _map = new HashMap<String, Object>();
		_map.put("auth", map);
		_map.put("user", jsonMap);
		_map.put("family", family(u.getId(), hospital));
		_map.put("account", other(u.getId(), hospital));
		msg.put("data", _map);
		String ip = u.getJson("ip") + "";
		String ipResult = HttpUtil.get(String.format("http://ip.taobao.com/service/getIpInfo.php?ip=%s", new Object[]{ip}));
		String isp = "未知运营商";
		Map ipResultMap = JSONUtil.fromJson(ipResult, new TypeReference<Map>(){});
		if (ipResultMap != null && (Integer)ipResultMap.get("code") == 0) {
			Map data = (Map)ipResultMap.get("data");
			isp = Tools.getDesc(data.get("region")) + Tools.getDesc(data.get("city")) + Tools.getDesc(data.get("isp"));
		}
		createMsgUser(u.getId(), hospital, "登录提醒", "系统提醒", String.format( "您的账户于%s使用%s网络登录，ip为%s,如果不是本人操作，请重置密码以保证账户安全。若是本人操作，请忽略本条消息。", new Object[]{DateUtil.formatDateByFormat(new Date(), DateUtil.DATETIME_FORMAT),isp, ip}), 7, u.getId() + "");
		return msg;
	}

	// 查询第3方登录信息
	public List other(Integer uid, Integer hospital) {
		List<Map> list = QBuilder.db("basedb").select("new map(pid as pid, patientId as patient_id, inNumber as in_number, clinicNumber as clinic_number, source as source, unionId as union_id)").from("UserAccount").where(new Where("uid=", uid).and("hospital=", hospital).and("status=", STATUS_ENABLE)).query().getResultObj();
		return list;
	}

	// 查询用户其他信息
	public List<Map> family(Integer uid, Integer hospital) {
		String content = "new map(up.phone as phone, up.patientId as patient_id, up.self as myself, up.cardType as card_type,up.cardNumber as card_number,up.medicalType as medical_type,up.medicalNumber as medical_number, up.name as name, up.gender as gender, up.age as age, up.id as pid,up.relation as relation)";
		List<Map> family = QBuilder.db("basedb").select(content).from("UserProfile as up").where(new Where("up.uid=", uid).and("up.hospital=", hospital).and("up.status=", STATUS_ENABLE)).query().getResultObj();
		List<Map> cards = QBuilder.db("basedb").select("new map(count(pc.pid) as card_count, pc.pid as pid)").from("PatientCard as pc").where(new Where("pc.uid=", uid).and("pc.hospital=", hospital).and("pc.status=", STATUS_ENABLE)).group("pc.pid").query().getResultObj();
		for (Map myLove:family) {
			myLove.put("card_count", 0);
			Integer pid = (Integer)myLove.get("pid");
			for (Map cardMap:cards) {
				if (((Integer)cardMap.get("pid")).equals(pid)) {
					myLove.put("card_count", cardMap.get("card_count"));
				}
			}
		}
		return family;
	}

	// 生成令牌
	public Map token(User user) {
		if (null == user) {
			return new HashMap();
		}
		Token token = new Token();
		token.setUid(user.getId());
		token.setStatus(STATUS_ENABLE);
		token.setUserName(user.getUserName());
		token.setPassword(user.getPassword());
		token.setHospital(user.getHospital());
		String from = Tools.getDesc(user.getJson("from"), "");
		if ("wechat".equals(from)) { // 微信用户
			token.setWechat(true);
			token.setExpireIn(-1);
			token.setToken(Tools.getDesc(user.getJson("token"), ""));
		}
		return token.genToken();
	}

	// 设置医院员工信息
	void setEmployeeInfo(User user, Map<String, Object> jsonMap) {
		Long birth = Tools.getLong(user.getBirthday() + "", -1L);
		if (birth > 0)
			jsonMap.put("age", birth2age(birth));
		else
			jsonMap.put("age", 0);
		jsonMap.put("birthday", birth < 0 ? "" : DateUtil.formatDate(new Date(birth)));
		jsonMap.put("employee_id", user.getEmployeeId());
		jsonMap.put("avatar", getDefaultAvatar(user));
		jsonMap.put("avatar", getDefaultAvatar(user));
		jsonMap.put("gender", Tools.getDesc(user.getGender() + "", ""));
		jsonMap.put("title", Tools.getDesc(user.getTitle(), ""));
		jsonMap.put("introduce", Tools.getDesc(user.getJson("introduce"), ""));
		jsonMap.put("specialty", Tools.getDesc(user.getJson("specialty"), ""));
		jsonMap.put("hospital_name", Tools.getDesc(user.getJson("hospital_name"), ""));
		jsonMap.put("dept_name", Tools.getDesc(user.getJson("dept_name"), ""));
		jsonMap.put("phone", Tools.getDesc(user.getPhone() + "", ""));
		jsonMap.put("position", Tools.getDesc(user.getJson("position"), "科主任"));
		jsonMap.put("teach_title", Tools.getDesc(user.getJson("teach_title"), "教授"));
		Map<String, Map> timeMap = JSONUtil.fromJson(Tools.getDesc(user.getJson("time"), "{}"), new TypeReference<Map<String, Map>>(){});
		if (timeMap == null)
			timeMap = new HashMap();
		/*Set<String> timeSet = timeMap.keySet();
		for (String timeKey:timeSet) {
			Map map = timeMap.get(timeKey);
			Set<String> halfMap = map.keySet();
			for (String halfKey:timeSet) {
				map.put(halfKey, Tools.getInt(Tools.getDesc(map.get(halfKey)).replace(".0", "")));
			}
		}*/
		jsonMap.put("time", timeMap);
		jsonMap.putAll(user.getJson());
		jsonMap.put("dept_id", user.getDeptId());
		jsonMap.remove("from");
		jsonMap.remove("ip");
		jsonMap.remove("token");
		// 医生1 科秘书2 科主任3
		jsonMap.put("role", Tools.getDesc(user.getJson("role"), "1"));
		List<Hospital> list = QBuilder.db("basedb").select().from("Hospital").where(new Where("hospital=", user.getDeptId()==null?0:user.getDeptId())).query().getResultObj();
		if (!isEmpty(list)) {
			Hospital hospitalObj = list.get(0);
			jsonMap.put("dept_name", hospitalObj.getName());
			jsonMap.put("hospital_name", hospitalObj.getDescr());
		}
		// 查找所在科室信息
		Integer deptId = user.getDeptId();
		List<Dept> employeeDepts = QBuilder.db("basedb").queryHql("from Dept where id=" + deptId+ " and hospital=" + user.getHospital());
		if (employeeDepts.size() > 0) {
			Dept eDept = employeeDepts.get(0);
			String employeeDeptId = eDept.getDeptId();
			String employeeDeptName = eDept.getDeptName();
			jsonMap.put("dept_id", employeeDeptId);
			jsonMap.put("dept_name", employeeDeptName);
		}
	}

	// 设置普通用户信息
	void setUserInfo(User user, Map<String, Object> jsonMap) {
		jsonMap.put("avatar", Tools.getDesc(user.getAvatar(), USER_AVATAR_M));
		jsonMap.put("city", Tools.getDesc(user.getCity(), ""));
		// 查找用户信息
		Integer uid = user.getId();
		List<UserProfile> userProfiles = QBuilder.db("basedb").queryHql("from UserProfile where uid=" + uid + " and self = " + SELF);
		if (userProfiles.size() > 0) {
			UserProfile userProfile = userProfiles.get(0);
			Long birth = Tools.getLong(userProfile.getBirthday() + "", -1L);
			jsonMap.put("birthday", birth < 0 ? "" : DateUtil.formatDate(new Date(birth)));
			jsonMap.put("gender", Tools.getDesc(userProfile.getGender() + "", ""));
			jsonMap.put("self", Tools.getDesc(userProfile.getSelf() + "", "0"));
			if (birth > 0) {
				jsonMap.put("age", birth2age(birth));
			} else {
				jsonMap.put("age", Tools.getDesc(userProfile.getAge() + "", ""));
			}
			jsonMap.put("phone", Tools.getDesc(userProfile.getPhone() + "", ""));
			jsonMap.put("card_type", Tools.getDesc(userProfile.getCardType() + "", ""));
			jsonMap.put("card_number", Tools.getDesc(userProfile.getCardNumber() + "", ""));
			jsonMap.put("medical_type", Tools.getDesc(userProfile.getMedicalType() + "", ""));
			jsonMap.put("medical_number", Tools.getDesc(userProfile.getMedicalNumber() + "", ""));
			jsonMap.put("patient_id", Tools.getDesc(userProfile.getPatientId() + "", ""));
			jsonMap.put("mail", Tools.getDesc(user.getMail() + "", ""));
			jsonMap.put("question", Tools.getDesc(user.getQuestion() + "", ""));
			jsonMap.put("answer", Tools.getDesc(user.getAnswer() + "", ""));
			jsonMap.put("address", Tools.getDesc(user.getAddress() + "", ""));
			jsonMap.put("user_name", Tools.getDesc(user.getUserName() + "", ""));
			jsonMap.put("nick_name", Tools.getDesc(user.getNickName() + "", ""));
			jsonMap.put("name", Tools.getDesc(user.getName() + "", ""));
			jsonMap.put("uid", Tools.getDesc(user.getId() + "", ""));
			jsonMap.put("json", userProfile.getJson());

		}
	}

	//注册
	public Message register(User user, UserProfile userProfile) {
		Message msg = new Message("注册成功");
		int hospital = user.getHospital();
		String userName = Tools.getDesc(user.getUserName());
		String password = Tools.getDesc(user.getPassword());
		String passwd = Tools.getDesc(user.getRepassword());
		String phone = Tools.getDesc(user.getPhone(), "-1");
		if (userName.length() < 4){ //用户名长度不合法
			msg = new Message(30023, "用户名长度不少于4个字符");
			return msg;
		}
		String match = "[a-zA-Z0-9_]*";
		if (!userName.matches(match)) { //用户名以字母或下划线开头
			msg = new Message(30024, "用户名以字母或下划线开头");
			return msg;
		}
		if (password.length() < 6) { //密码长度不合法
			msg = new Message(30025, "密码长度不少于6个字符");
			return msg;
		}
		if (!password.matches(match)) { //密码不能包含非法字符
			msg = new Message(30026, "密码包含非法字符");
			return msg;
		}
		if (!passwd.equals(password)) { //两次密码不一致
			msg = new Message(30027, "两次密码不一致");
			return msg;
		}
		if (!SIGN_PATIENT.equals(user.getType()) && !SIGN_EMPLOYEE.equals(user.getType()) && !USER_EMPLOYEE.equals(user.getType())) {
			user.setType(USER_PATIENT);
		}
		List<User> list = QBuilder.db("basedb").select().from("User as u").where(new Where("u.status=", STATUS_ENABLE).and("u.hospital=", hospital).and("(u.userName = '" + userName + "' or u.phone='" + userName + "' or u.phone='" + phone + "')").and("u.type=", user.getType())).page(1, 1).query().getResultObj();
		if (list.size() > 0) { //用户已经存在
			msg = new Message(30029, "用户已经存在");
			return msg;
		}
		String lastIp = Tools.getDesc(user.getJson("ip"), "");
		user.setLastIp(lastIp);
		user.setLastLogin(System.currentTimeMillis());
		Integer uid = (Integer)DBTools.db("basedb").addItem(user);
		userProfile.setUid(user.getId());
		userProfile.setSelf(SELF); // 本人账户
		DBTools.db("basedb").addItem(userProfile);
		Map map = new HashMap();
		map.put("uid", uid);
		map.put("pid", userProfile.getId());
		msg.put("data", map);
		createMsgUser(uid, hospital, "注册成功提醒", "系统提醒", "恭喜您成功注册本软件，祝您使用愉快。", 7, uid + "");
		return msg;
	}

	//
	public void createMsgUser(Integer uid, Integer hospital, String title, String summary, String content, Integer category, String oid) {
		Information info = new Information();
		info.setUid(uid);
		info.setTitle(title);
		info.setSumary(summary);
		info.setContent(content);
		info.setCategory(category);
		info.setHospital(hospital);
		info.setOid(oid);
		DBTools.db("basedb").addItem(info);
	}

	// 身份证15位不全18位
	public String fixPersonIDCode(String personIDCode) {
		if (personIDCode == null || personIDCode.trim().length() != 15) {
			return personIDCode;
		}
		String id17 = personIDCode.substring(0, 6) + "19"
				+ personIDCode.substring(6, 15); // 15为身份证补\'19\'
		char[] code = { '1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2' }; // 11个
		int[] factor = { 0, 2, 4, 8, 5, 10, 9, 7, 3, 6, 1, 2, 4, 8, 5, 10, 9, 7 }; // 18个;
		int[] idcd = new int[18];
		int i;
		int j;
		int sum;
		int remainder;
		for (i = 1; i < 18; i++) {
			j = 17 - i;
			if(id17.substring(j, j + 1).trim().length() == 0){
			    continue;
			}
			idcd[i] = Integer.parseInt(id17.substring(j, j + 1));
		}
		sum = 0;
		for (i = 1; i < 18; i++) {
			sum = sum + idcd[i] * factor[i];
		}
		remainder = sum % 11;
		String lastCheckBit = String.valueOf(code[remainder]);
		return id17 + lastCheckBit;
	}


	// 根据uid查询用户信息
	User userByUid (Integer uid) {
		List<Integer> uids = new ArrayList<Integer>();
		uids.add(uid);
		Map<Integer, User> map =  usersByUids(uids);
		User user =  Tools.getObject(map.get(uid), null);
		return user;
	}

	// 根据所给uid查询对应的用户信息
	Map<Integer, User> usersByUids(List<Integer> uids) {
		if (uids == null) return new HashMap<Integer, User>();
		StringBuffer buffer = new StringBuffer();
		for (int i = 0; i < uids.size(); i++) {
			Integer uid = uids.get(i);
			buffer.append(uid + ",");
		}

		if (buffer.length() == 0) return new HashMap<Integer, User>();
		String allUid = buffer.toString();
		if (allUid.endsWith(",")) {
			allUid = allUid.substring(0, allUid.length() - 1);
		}
		List<User> users = QBuilder.db("basedb").queryHql("from User where id in (" + allUid + ")");
		Map<Integer, User> map = new HashMap<Integer, User>();
		for (int i = 0; i < users.size(); i++) {
			User user = users.get(i);
			Integer uid = user.getId();
			map.put(uid, user);
		}
		return map;
	}

	// 根据uid查询自己
	UserProfile selfProfileByUid(Integer uid) {
		if (uid == null) return null;
		List<UserProfile> userprofiles = QBuilder.db("basedb").queryHql("from UserProfile where uid=" + uid + " and status=" + STATUS_ENABLE + " and self=" + SELF);
		if (isEmpty(userprofiles))
			return null;
		return userprofiles.get(0);
	}

	// 根据uid查询就诊人
	Map<Integer, UserProfile> userprofileByUid(Integer uid) {
		Map<Integer, UserProfile> map = new HashMap<Integer, UserProfile>();
		if (uid == null) return map;
		List<UserProfile> userprofiles = QBuilder.db("basedb").queryHql("from UserProfile where uid=" + uid + " and status=" + STATUS_ENABLE);
		for (int i = 0; i < userprofiles.size(); i++) {
			UserProfile userprofile = userprofiles.get(i);
			Integer pid = userprofile.getId();
			map.put(pid, userprofile);
		}
		return map;
	}

	// 完善个人信息
	public Message complete(User user, UserProfile userProfile) {
		Message msg = new Message("信息提交成功");
		int hospital = user.getHospital();
		List<User> users = QBuilder.db("basedb").select().from("User").where(new Where("hospital=", hospital).and("status = ", STATUS_ENABLE).and("id=", user.getId())).query().getResultObj();
		List<UserProfile> userProfiles = QBuilder.db("basedb").select().from("UserProfile").where(new Where("hospital=", hospital).and("status = ", STATUS_ENABLE).and("uid=", user.getId()).and("self=", SELF)).query().getResultObj();
		if (users.size() == 0 || userProfiles.size() == 0) {
			return new Message(30041, "用户不存在");
		}
		User oldUser = users.get(0);
		String oldPhone = Tools.getDesc(oldUser.getPhone(), "");
		userProfile.setId(userProfiles.get(0).getId());
		String phone = Tools.getDesc(user.getPhone(), "");
		if (!oldPhone.equals(phone)) {
			if (!isChinaPhoneLegal(phone))
				return new Message(30031, "手机号不合法");
			List<User> list = QBuilder.db("basedb").select().from("User as u").where(new Where("u.status=", STATUS_ENABLE).and("u.hospital=", hospital).and("(u.userName = '" + phone + "' or u.phone='" + phone + "')").and("u.type=", USER_PATIENT)).page(1, 1).query().getResultObj();
			if (!isEmpty(list))
				return new Message(30031, "该手机号已经绑定了其他账户");
		}
		user.setAvatar(getDefaultAvatar(users.get(0)));
		String cardNumber = fixPersonIDCode(userProfile.getCardNumber());
		if ("".equals(userProfile.getCardType()))
			userProfile.setCardType("身份证");
		if ((Tools.getDesc(userProfile.getCardType(), "身份证")).contains("身份证")) {
			// 校验身份证号码合法性
			if (cardNumber != null && !"".equals(cardNumber)) {
				if(!IdCardUtil.validateIdCard18(cardNumber)){
					msg = new Message(30028, "证件号码不正确");
					return msg;
				}
				user.setBirthday(IdCardUtil.getBirth(cardNumber));
				user.setGender((IdCardUtil.getGender(cardNumber))%2);
				userProfile.setGender(user.getGender());
				userProfile.setBirthday(user.getBirthday());
				userProfile.setAge(IdCardUtil.getAgeByIdCard(cardNumber));
				userProfile.setCardType("身份证");
			}
		}
		userProfiles = QBuilder.db("basedb").select().from("UserProfile").where(new Where("hospital=", hospital).and("status = ", STATUS_ENABLE).and("cardNumber=", userProfile.getCardNumber()).and("self=", FAMILY).and("uid=", user.getId()).and("id!=", userProfile.getId())).query().getResultObj();
		if (userProfiles.size() > 0) {
			return new Message(30042, "该身份证已被您绑定了其他就诊人");
		}
		userProfiles = QBuilder.db("basedb").select().from("UserProfile").where(new Where("hospital=", hospital).and("status = ", STATUS_ENABLE).and("cardNumber=", userProfile.getCardNumber()).and("self=", SELF).and("uid!=", user.getId())).query().getResultObj();
		if (userProfiles.size() > 0) {
			return new Message(30042, "该身份证已被绑定了账户,如需申诉请联系我们");
		}
		user.setCity((user.getCity() == null || user.getCity() == 0) ? 510 : user.getCity());
		if (user.getName() != null) {
			String name = user.getName();
			String regexStr = "^[\\u4E00-\\u9FA5A-Za-z0-9_.%&',;=?$\\x22]{2,20}$";
			if (!name.matches(regexStr)) {
				return new Message(30041, "姓名必须为字符数字下划线点");
			}
			if (name.length() > 20 || name.length() < 2 ) {
				return new Message(30041, "姓名为2-20位汉字");
			}
		}
		DBTools.db("basedb").modItem(user, user.getId());
		DBTools.db("basedb").modItem(userProfile, userProfile.getId());
		return msg;
	}

	// 查询就诊卡
	public List<Map> card(PatientCard patientCard) {
		List<Map> patientCards = QBuilder.db("basedb").select("new map(id as id, pid as pid, cardName as card_name, number as number, branchName as branch_name)").from("PatientCard").where(new Where("status = ", STATUS_ENABLE).and("pid=", patientCard.getPid()).and("uid=", patientCard.getUid())).query().getResultObj();
		return patientCards;
	}
%>
